package com.relax.zk;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.UUID;

@SpringBootTest
public class ZKWatch {

    /**
     * 获取zookeeper连接时所需要的服务器连接信息，格式为主机名：端口号;多个服务使用“，”分割
     */
    public static final String CONNECT_STRING = "127.0.0.1:2181";

    /**
     * 请求会话超时时长
     */
    public static final int SESSIONT_IMEOUT = 5000;

    private static ZooKeeper zk;

    public static void main(String[] args) throws Exception {
        String watchPath = "/watch_zk";
        zk = new ZooKeeper("192.168.64.4:2181", 5000, new Watcher() {
            @Override
            public void process(WatchedEvent event) {
                // 事件类型
                Event.EventType type = event.getType();
                // 节点路径
                String path = event.getPath();
                System.out.println("节点路径 = " + path + " 事件类型 = " + type);

                try {
                    // 注册监听 节点的数据变化
                    // 事件： NodeDeleted， NodeDataChanged
                    // 触发： delete, setData
                    byte[] data = zk.getData(watchPath, true, null);
                    System.out.println("节点查询数据=="+new String(data));

                    // 注册监听 子节点个数变化
                    // 事件： NodeChildrenChanged, NodeDeleted
                    // 触发： create/delete子节点, delete当前给定节点
                    List<String> children = zk.getChildren(watchPath, true);
                    System.out.println("子节点查询数据=="+children);

                    // 注册监听 该节点的变化（被创建，被删除，数据被改变）
                    // 事件： NodeCreated， NodeDeleted， NodeDataChanged
                    // 触发： create,  delete,  setData
                    Stat exists = zk.exists(watchPath, true);
                } catch (Exception e) {
                    e.printStackTrace();
                }

                // 根据监听的相应的事件类型和节点,编写对应业务逻辑
                if (type == Event.EventType.NodeDeleted && event.getPath().equals(watchPath)) {
                    System.out.println("节点的数据变化---删除");
                } else if (type == Event.EventType.NodeDataChanged) {
                    System.out.println("节点的数据变化---修改");
                } else if (type == Event.EventType.NodeCreated) {
                    System.out.println("节点的数据变化---创建");
                } else if (type == Event.EventType.NodeChildrenChanged) {
                    System.out.println("子节点个数变化---创建/删除");
                } else if (type == Event.EventType.NodeDeleted) {
                    System.out.println("子节点个数变化---删除");
                }

            }
        });

        // 判断监听节点是否，不存在则创建
        if (zk.exists(watchPath, null) == null) {
            System.out.println("创建节点" + watchPath);
            String result = zk.create(watchPath, "watchData".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
            System.out.println("创建节点,节点" + result);
        }

        // 保证watcer线程一直工作
        Thread.sleep(Long.MAX_VALUE);
        System.out.println("程序关闭");

        // 启动监听就不会关闭zk链接
        // zk.close();
    }




    @Before
    public void getZKConnection() throws Exception {
        zk = new ZooKeeper("192.168.64.4:2181", 5000, null);
    }

    /**
     * 关闭ZK连接
     */
    @After
    public void closeZKConnection() throws InterruptedException {
        zk.close();
    }

    @Test
    public void createZKNode() throws Exception {
        zk.setData("/watch_zk", UUID.randomUUID().toString().getBytes(),-1);

    }

}
